package com.tbvtc.agriculturalcreditchainserver2025.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.tbvtc.agriculturalcreditchainserver2025.comment.Token.JwtUtil;
import com.tbvtc.agriculturalcreditchainserver2025.constant.RedisConstant;
import com.tbvtc.agriculturalcreditchainserver2025.exception.FoodException;
import com.tbvtc.agriculturalcreditchainserver2025.mapper.AuthMapper;
import com.tbvtc.agriculturalcreditchainserver2025.service.AuthService;
import com.tbvtc.agriculturalcreditchainserver2025.service.SmsService;
import com.tbvtc.agriculturalcreditchainserver2025.utils.CodeUtil;
import com.tbvtc.agriculturalcreditchainserver2025.utils.ResultCodeEnum;
import com.tbvtc.agriculturalcreditchainserver2025.vo.AuthUser;
import com.tbvtc.agriculturalcreditchainserver2025.vo.CaptchaVo;
import com.tbvtc.agriculturalcreditchainserver2025.vo.LoginDto;
import com.tbvtc.agriculturalcreditchainserver2025.vo.UserVo;
import com.tbvtc.agriculturalcreditchainserver2025.vo.farmerVo.loginVo;
import com.wf.captcha.SpecCaptcha;
import com.wf.captcha.base.Captcha;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class AuthServiceImpl implements AuthService {


    @Autowired
    private AuthMapper authMapper;

    @Autowired
    @Qualifier("redisTemplate1") // 指定默认的RedisTemplate
    private RedisTemplate redisTemplate;
    @Autowired
    private SmsService smsService;

    @Override
    public void registerFarmer(UserVo userVo) {
        AuthUser user = BeanUtil.copyProperties(userVo, AuthUser.class);
        user.setUsername(UUID.randomUUID().toString());
        //进行加密
        //获取redis中的手机验证码
        String code1 = (String) redisTemplate.opsForValue().get(RedisConstant.APP_LOGIN+ userVo.getPhone());
        if (!user.getCode().equals(code1)) {
            throw new FoodException(ResultCodeEnum.APP_LOGIN_CODE_ERROR);
        }
        List<String> list = authMapper.selectPhone();
        list.forEach(s -> {
            if (s.equals(user.getPhone())) {
                throw new FoodException(ResultCodeEnum.APP_REGISTER_PHONE_EXIST);
            }
        });
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        if (user.getRoleId().equals("1")) {
            user.setAddress("0xf4bd5d2c2c62cb892d2ec55efd5e61ce2dfe5cca");
            user.setUserImage("QmVTXZzsq9hve2RXGvzsYwFk4KzbNRp2bqGBjL91yxQs8y");
        } else if (user.getRoleId().equals("2")) {
            user.setAddress("0xd8b77e1e5c1edc86bc23e9c456e6ce5288d2184b");
            user.setUserImage("QmRMPLjFTAv7EafUPjgMnQk8KFEswFyin5N79sCVJxrg2n");
        } else if (user.getRoleId().equals("3")) {
            //注册完成需要审核
            user.setIsAudit(1);
            user.setAddress("0x96f911c73ef70f39eb43915c1e810ae655b64091");
            user.setUserImage("QmY2dKKemnFA6prAxMXKLuKzNzpWu79U3k4Ehkai83xdcY");
        } else if (user.getRoleId().equals("4")) {
            user.setAddress("0xd448f23960d3db6cb502ef429021ece35087714e");
            user.setUserImage("QmTy2zLzrsMjY3fBuxQhJjX6fCKcmpqSEWXaryTA3GziFZ");
        }
        String s = DigestUtil.md5Hex(user.getPassword(), "UTF-8");
        user.setPassword(s);
        authMapper.register(user);
    }

    @Override
    public loginVo LoginFarmer(LoginDto loginDto) {
        loginDto.setPassword(DigestUtil.md5Hex(loginDto.getPassword(), "UTF-8"));

        loginVo login = authMapper.Login(loginDto);
        if (login == null) {
            throw new FoodException(ResultCodeEnum.APP_LOGIN_PHONE_ERROR);
        }
        Long audit = authMapper.getAudit(loginDto.getPhone());
        Long disable = authMapper.getDisable(loginDto.getPhone());
        if (audit == 1) {
            throw new FoodException(ResultCodeEnum.USER_NOT_AUTH);
        }
        if (disable == 1) {
            throw new FoodException(ResultCodeEnum.USER_DISABLE);
        }

        //获取redis中的Code
        String code = (String) redisTemplate.opsForValue().get(loginDto.getKey());
        if (code == null) {
            throw new FoodException(ResultCodeEnum.ADMIN_CAPTCHA_CODE_EXPIRED);
        }
        //忽略大小写
        if (!code.equalsIgnoreCase(loginDto.getCode())) {
            throw new FoodException(ResultCodeEnum.APP_LOGIN_CODE_ERROR);
        }
        String token = JwtUtil.createToken(login.getPhone(), login.getId());
        login.setToken(token);
        return login;
    }

    @Override
    public CaptchaVo captcha() {
        SpecCaptcha specCaptcha = new SpecCaptcha(130, 48, 4); // 验证码
        specCaptcha.setCharType(Captcha.TYPE_DEFAULT); // 纯数字
        String code = specCaptcha.text().toLowerCase();  // 验证码
        String key = "admin:login:" + UUID.randomUUID(); // keyz
        String image = specCaptcha.toBase64(); // base64
        redisTemplate.opsForValue().set(key, code, 60, TimeUnit.SECONDS); // 设置时长为十分钟
//        redisTemplate.opsForValue().set(key, code, 60, TimeUnit.SECONDS); // 设置时长为十分钟

        return new CaptchaVo(image, key);
    }

    @Override
    public void getCode(String phone) {
        String code = CodeUtil.getRandomCode(6); //
        String key = "app:login:" + phone; // key
        //1. 检查手机号码是否为空
        if (!StringUtils.hasText(phone)) { // 若为空，响应手机号码为空
            throw new FoodException(ResultCodeEnum.APP_LOGIN_PHONE_EMPTY);
        }
        //2. 检查Redis中是否已经存在该手机号码的key
        boolean hasKey = redisTemplate.hasKey(key);
        if (hasKey) {
            //若存在，则检查其存在的时间
            Long ttl = redisTemplate.getExpire(key, TimeUnit.SECONDS);
            if (600 * 6 * 24 - ttl < 60) {
                //若存在时间不足一分钟，响应发送过于频繁
                throw new FoodException(ResultCodeEnum.APP_SEND_SMS_TOO_OFTEN);
            }
        }

        //3.发送短信，并将验证码存入Redis
//        String verifyCode = VerifyCodeUtil.getVerifyCode(6);
        smsService.sendCode(phone, code);
        //设置时长为十分钟
        redisTemplate.opsForValue().set(key, code, 600 * 6 * 24, TimeUnit.SECONDS);
    }

    @Override
    public void findPassword(String phone, String newPassword, String code) {
        String code1 = (String) redisTemplate.opsForValue().get("app:login:" + phone);
        if (!code.equals(code1)) {
            throw new FoodException(ResultCodeEnum.APP_LOGIN_CODE_ERROR);
        }
        newPassword = DigestUtil.md5Hex(newPassword, "UTF-8");
        authMapper.findPassword(phone, newPassword);
    }


}
